package tenant

import (
	"cgs-server/server/base"
	"cgs-server/server/model"
	"errors"
	"go.mongodb.org/mongo-driver/bson"
	"time"
)

type TenantInfoService interface {
	base.Service
	// 根据租户id获取信息
	GetByTenantId(tenantId string, user *model.User) (*TenantInfo, error)
	// 根据租户id删除信息
	RemoveLogicByTenantId(tenantId string, user *model.User) error
}

func NewTenantInfoService() TenantInfoService {
	return &tenantInfoService{
		infoRepo: NewTenantInfoRepository(),
	}
}

type tenantInfoService struct {
	base.ServiceImpl
	infoRepo TenantInfoRepository
}

func (t *tenantInfoService) Save(mdl *model.DataUserModel) error {
	if info, ok := mdl.Data.(*TenantInfo); ok {
		// 查找
		if info.TenantId == "" {
			return errors.New("TenantId is required.")
		}
		mdl.Filter = &bson.M{
			"tenantId": info.TenantId,
		}
		one, _ := t.infoRepo.FindOne(mdl)
		if one == nil {
			// 没找到
			return t.infoRepo.Insert(mdl)
		} else {
			return errors.New("Tenant info is already exists.")
		}
	} else {
		return model.NewTypeError("tenantInfo")
	}
}

func (t *tenantInfoService) Update(mdl *model.DataUserModel) error {
	if info, ok := mdl.Data.(*TenantInfo); ok {
		if info.TenantId == "" {
			return errors.New("TenantId id is required.")
		}
		if info.Account.EndDate.Before(info.Account.BeginDate) {
			return errors.New("The end time can not before begin time.")
		}
		err := t.infoRepo.Update(mdl)
		return err
	} else {
		return model.NewTypeError("tenantInfo")
	}
}

func (t *tenantInfoService) RemoveLogic(mdl *model.DataUserModel) error {
	if info, ok := mdl.Data.(*TenantInfo); ok {
		if info.Id.IsZero() {
			return errors.New("TenantIdInfo id is required.")
		}
		err := t.infoRepo.DeleteLogic(mdl)
		return err
	} else {
		return model.NewTypeError("tenantInfo")
	}
}

func (t *tenantInfoService) RemoveLogicByTenantId(tenantId string, user *model.User) error {
	info := &TenantInfo{}
	info.TenantId = tenantId
	err := t.infoRepo.DeleteLogic(&model.DataUserModel{
		Data: info,
		User: user,
	})
	return err
}

func (t *tenantInfoService) List(mdl *model.DataUserModel) (interface{}, error) {
	return t.infoRepo.Find(mdl)
}

func (t *tenantInfoService) GetOne(mdl *model.DataUserModel) (interface{}, error) {
	return t.infoRepo.FindOne(mdl)
}

func (t *tenantInfoService) GetByTenantId(tenantId string, user *model.User) (*TenantInfo, error) {
	info := &TenantInfo{}
	one, _ := t.infoRepo.FindOne(&model.DataUserModel{
		Data: info,
		Filter: &bson.M{
			"tenantId": tenantId,
		},
		User: user,
	})
	if one == nil {
		// 没找到，新增一个
		isTrial := true
		info.Account = Account{
			Version:       "Community",
			BeginDate:     time.Now(),
			EndDate:       time.Now().AddDate(0, 0, 15),
			IsTrial:       &isTrial,
			RemainingDays: 0,
		}
		info.TenantId = tenantId
		err := t.infoRepo.Insert(&model.DataUserModel{
			Data: info,
			User: user,
		})
		if err != nil {
			return nil, err
		}
		info.Account.CalculateRemainDays()
		return info, nil
	} else {
		info = one.(*TenantInfo)
		info.Account.CalculateRemainDays()
		info.Account.Version = "Community"
		return info, nil
	}
}
